//package com.kingyea.mobilepolice.util;
//
//import org.apache.ibatis.executor.parameter.ParameterHandler;
//import org.apache.ibatis.executor.statement.RoutingStatementHandler;
//import org.apache.ibatis.executor.statement.StatementHandler;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.ParameterMapping;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
//
//import java.sql.Connection;
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.util.List;
//import java.util.Properties;
//
//@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
//public class PagePlugin implements Interceptor {
//
//    private static String dialect = "mysql";
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
//        StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
//        BoundSql boundSql = delegate.getBoundSql();
//        Object parameterObject = boundSql.getParameterObject();
//
//        if (parameterObject != null && parameterObject instanceof BasePage<?>) {
//
//            BasePage<?> page = (BasePage<?>) parameterObject;
//            if (page.isPageAble) {
//                MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
//                Connection connection = (Connection) invocation.getArgs()[0];
//                String sql = boundSql.getSql();
//                this.setTotalRecord(page, mappedStatement, connection, parameterObject);
//                String pageSql = this.getPageSql(page, sql);
//                ReflectUtil.setFieldValue(boundSql, "sql", pageSql);
//            }
//        }
//        return invocation.proceed();
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        return Plugin.wrap(target, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//        PagePlugin.dialect = properties.getProperty("dialect");
//    }
//
//    private String getPageSql(BasePage<?> page, String sql) {
//        StringBuffer sqlBuffer = new StringBuffer(sql);
//        if ("mysql".equalsIgnoreCase(PagePlugin.dialect)) {
//            return getMysqlPageSql(page, sqlBuffer);
//        } else if ("oracle".equalsIgnoreCase(PagePlugin.dialect)) {
//            return getOraclePageSql(page, sqlBuffer);
//        }
//        return sqlBuffer.toString();
//    }
//
//    private String getMysqlPageSql(BasePage<?> page, StringBuffer sqlBuffer) {
//        int offset = (page.getPageNum () - 1) * page.getPageSize();
//        sqlBuffer.append(" limit ").append(offset).append(",").append(page.getPageSize());
//        return sqlBuffer.toString();
//    }
//
//    private String getOraclePageSql(BasePage<?> page, StringBuffer sqlBuffer) {
//        int offset = (page.getPageNum () - 1) * page.getPageSize() + 1;
//        sqlBuffer.insert(0, "select u.*, rownum r from (").append(") u where rownum < ").append(offset + page.getPageSize());
//        sqlBuffer.insert(0, "select * from (").append(") where r >= ").append(offset);
//        //select * from (select u.*, rownum r from (select * from t_user) u where rownum < 31) where r >= 16
//        return sqlBuffer.toString();
//    }
//
//    private void setTotalRecord(BasePage<?> page,
//                                MappedStatement mappedStatement, Connection connection, Object parameterObject) {
//        BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
//        String sql = boundSql.getSql();
//        String countSql = this.getCountSql(sql);
//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//        BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, parameterMappings, page);
//
//        ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBoundSql);
//        try (PreparedStatement pstmt = connection.prepareStatement(countSql)) {
//            parameterHandler.setParameters(pstmt);
//            try (ResultSet rs = pstmt.executeQuery()) {
//                if (rs.next()) {
//                    int totalRecord = rs.getInt(1);
//                    page.setTotal (totalRecord);
//                }
//            } catch (SQLException e) {
//                e.printStackTrace();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    private String getCountSql(String sql) {
//        int index = sql.indexOf("from");
//        return "select count(*) " + sql.substring(index);
//    }
//
//}
